package com.platform.modules.mall.activity.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.Constant;
import com.platform.common.utils.DateUtils;
import com.platform.common.utils.StringUtils;
import com.platform.modules.mall.activity.entity.bo.*;
import com.platform.modules.mall.activity.restrict.ActivityVerify;
import com.platform.modules.mall.activity.restrict.GoodsMaxOrderVerify;
import com.platform.modules.mall.activity.restrict.RestrictInterface;
import com.platform.modules.mall.activity.restrict.RestrictFactory;
import com.platform.modules.mall.activity.rule.RuleAbstract;
import com.platform.modules.mall.activity.rule.RuleFactory;
import com.platform.modules.mall.activity.service.GoShoppingService;
import com.platform.modules.mall.activity.type.ActivityTypeInterface;
import com.platform.modules.mall.activityV2.entity.ParticipantBo;
import com.platform.modules.mall.activityV2.entity.WinnerBo;
import com.platform.modules.mall.activityV2.restrict.RestrictFactoryV2;
import com.platform.modules.mall.activityV2.restrict.RestrictInterfaceV2;
import com.platform.modules.mall.activityV2.rule.RuleFactoryV2;
import com.platform.modules.mall.activityV2.rule.RuleInterface;
import com.platform.modules.mall.entity.*;
import com.platform.modules.mall.goods.utils.CreateOrderUtil;
import com.platform.modules.mall.service.MallGoodsService;
import com.platform.modules.mall.service.MallGoodsToActivityService;
import com.platform.modules.mall.service.MallOrderGoodsService;
import com.platform.modules.mall.service.MallOrderService;
import com.platform.modules.mall.utils.MyStringUtil;
import com.platform.modules.mch.service.MchOrderService;
import com.platform.modules.sys.service.SysConfigService;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;


@Service("goShoppingServiceImpl")
public class GoShoppingServiceImpl implements GoShoppingService {

    @Autowired
    private ActivityVerify activityVerify;
    @Autowired
    private RestrictFactory restrictFactory;
    @Autowired
    private RuleFactory ruleFactory;
    @Autowired
    private MallGoodsService mallGoodsService;
    @Autowired
    private MallOrderService mallOrderService;
    @Autowired
    private MallGoodsToActivityService mallGoodsToActivityService;
    @Autowired
    private MallOrderGoodsService mallOrderGoodsService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private GoodsMaxOrderVerify goodsMaxOrderVerify;
    @Resource
    private MchOrderService mchOrderService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized ActivityOrderVo goShopping(ActivityGoshoppingBo bo) {
        /*验证活动日期*/
        MallActivityEntity activity = activityVerify.verifyContext(bo.getActivityId());

        /*获得活动限制规则实现类*/
        RestrictInterface restrict = restrictFactory.getRestrict(activity);
        restrict.verify(bo, activity);

        /*获得活动相关的商品，活动限制有影响时，过滤限制的商品*/
        List<MallGoodsToActivityEntity> list = restrict.getList(activity,bo);
        /*获得获得领取规则实现类*/
        //RuleAbstract rule = ruleFactory.getRule(activity,list,bo);
        ActivityTypeInterface rule =ruleFactory.getRuleNew(activity,list,bo);

        int num =list.size();
        MallGoodsEntity goodsEntity=null;
        MallGoodsToActivityEntity entity=null;

        boolean success=false;
        for (int i=0;i<num;i++){
            /*根据规则获得活动商品*/
            entity = rule.getEntity();
            /*规矩规则没有活动任何的活动商品*/
            if (entity==null){
                throw ActivityResultStatus.buildException(ActivityResultStatus.Status.GOODS_NUMBER_BUZHU);
            }
            /*查看商品是否存在*/
            goodsEntity=mallGoodsService.getById(entity.getGoodsId());
            if (goodsEntity==null){
                rule.delEntity(entity);
                continue;
            }

//            MallGoodsEntity goods = mallGoodsService.getById(entity.getGoodsId());
//            if (goods==null){
//                rule.delEntity(entity);
//                continue;
//            }

//            boolean bool = mallGoodsService.lambdaUpdate().setSql("goods_number=goods_number-" + bo.getNumber())
//                    .eq(MallGoodsEntity::getId, entity.getGoodsId())
//                    .eq(MallGoodsEntity::getIsOnSale,1)
//                    .eq(MallGoodsEntity::getIsDelete,1)
//                    .ge(MallGoodsEntity::getGoodsNumber, bo.getNumber()).update();

            /*减扣商品，校验商品库存*/
            boolean bool = rule.delGoodsNum(entity.getGoodsId(), bo.getNumber());

            if (!bool){
                rule.delEntity(entity);
                continue;
            }

            /*减扣活动商品库存*/
            boolean enbool = mallGoodsToActivityService.lambdaUpdate().setSql("expend_count=expend_count-"+bo.getNumber())
                    .eq(MallGoodsToActivityEntity::getId, entity.getId())
                    .ge(MallGoodsToActivityEntity::getExpendCount, bo.getNumber())
                    .update();
            if (!enbool){
                rule.delEntity(entity);
                continue;
            }

            success=true;
            break;
        }
        /*抽取所有的商品后*/
        if (!success){
            throw ActivityResultStatus.buildException(ActivityResultStatus.Status.GOODS_NOT);
        }

        Integer number = restrict.getNumber(bo, activity);

        restrict.successAfter(bo);

        MallOrderEntity order = CreateOrderUtil.initOrder(activity, goodsEntity, bo);
        mallOrderService.save(order);

        MallOrderGoodsEntity orderGoodsVo = new MallOrderGoodsEntity();
        orderGoodsVo.setOrderId(order.getId());
        orderGoodsVo.setGoodsId(goodsEntity.getId());
        orderGoodsVo.setGoodsSn(goodsEntity.getGoodsSn());
        orderGoodsVo.setGoodsName(goodsEntity.getName());
        orderGoodsVo.setListPicUrl(goodsEntity.getListPicUrl());
        orderGoodsVo.setMarketPrice(goodsEntity.getMarketPrice());
        orderGoodsVo.setRetailPrice(goodsEntity.getRetailPrice());
        orderGoodsVo.setNumber(bo.getNumber());
        // 设置微信优惠标识
        orderGoodsVo.setCouponTag(order.getActivityType());
        mallOrderGoodsService.add(orderGoodsVo);

        ActivityOrderVo vo =new ActivityOrderVo();
        vo.setMallGoodsToActivityEntity(entity);
        vo.setOrderId(order.getId());
        vo.setOrderSn(order.getOrderSn());
        vo.setPayType(order.getPayType());
        vo.setActivityId(activity.getId());
        vo.setNumber(number-bo.getNumber());
        vo.setGoodsType(goodsEntity.getGoodsType());
        return vo;
    }


    @Autowired
    private RestrictFactoryV2 restrictFactoryV2;

    @Autowired
    private RuleFactoryV2 ruleFactoryV2;

    /**
     *  1.验证活动日期信息
     *      1.1 根据活动信息，获得限制规则
     *      1.2 根据活动信息，获得活动规则
     *  2.根据限制规则获得 输入参与者信息， 输出  活动对象=可抽奖次数、可选取商品、活动规定商品获取方式（抽奖、直购、轮询）
     *  3.根据活动规则，输入活动对象，输出  中奖对象=中奖的商品、剩余次数、可选取的商品
     *  4.根据中奖对象创建订单
     * @param bo    参与抽奖的用户信息：参加的活动、手机、选中的商品id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WinnerBo goShoppingTow(ActivityGoshoppingBo bo) {
        /*todo 已经实现了不同的限制方式，领取方式。目前需要前端配合进行测试，并定义返回的参数*/
        /**验证活动日期*/
        MallActivityEntity activity = activityVerify.verifyContext(bo.getActivityId());
        /**限制规则对象*/
        RestrictInterfaceV2 restrictInterfaceV2 = restrictFactoryV2.restrictInterface(activity.getWhitelistConfine());
        /**领取方式对象*/
        RuleInterface rule = ruleFactoryV2.ruleInterface(activity.getActivityType());
        /**参与抽奖对象*/
        ParticipantBo restrict = restrictInterfaceV2.restrict(bo,activity);
        restrict.setActivityId(activity.getId());
        restrict.setRequestNum(bo.getNumber());
        /**中奖对象*/
        WinnerBo winnerBo = rule.execute(restrict);
        /**创建订单*/
        MallOrderEntity order = buildOrder(winnerBo, activity, bo);
        /**设置返回信息*/
        setWinnerBoData(winnerBo, activity, bo,order);

        return winnerBo;
    }


    /**
     * 设置返回的参数信息
     * @param winnerBo
     * @param activity
     * @param bo
     * @param order
     */
    private  void setWinnerBoData(WinnerBo winnerBo, MallActivityEntity activity, ActivityGoshoppingBo bo, MallOrderEntity order) {
        winnerBo.setNeedToPay(activity.getNeedToPay());

    }

    /**
     * 创建订单和订单详情商品表
     * @param winnerBo
     * @param activity
     * @param bo
     */
    private MallOrderEntity buildOrder(WinnerBo winnerBo,MallActivityEntity activity,ActivityGoshoppingBo bo){

        MallGoodsEntity goodsEntity = winnerBo.getGoodsEntity();

        MallOrderEntity order = CreateOrderUtil.initOrder(activity, goodsEntity, bo);
        mallOrderService.save(order);

        MallOrderGoodsEntity orderGoodsVo = new MallOrderGoodsEntity();
        orderGoodsVo.setOrderId(order.getId());
        orderGoodsVo.setGoodsId(goodsEntity.getId());
        orderGoodsVo.setGoodsSn(goodsEntity.getGoodsSn());
        orderGoodsVo.setGoodsName(goodsEntity.getName());
        orderGoodsVo.setListPicUrl(goodsEntity.getListPicUrl());
        orderGoodsVo.setMarketPrice(goodsEntity.getMarketPrice());
        orderGoodsVo.setRetailPrice(goodsEntity.getRetailPrice());
        orderGoodsVo.setNumber(bo.getNumber());
        // 设置微信优惠标识
        orderGoodsVo.setCouponTag(order.getActivityType());
        mallOrderGoodsService.add(orderGoodsVo);

        return order;
    }


    @Override
    public ActivityInfoVo activityInfo(ActivityGoshoppingBo bo) {

        MallActivityEntity mallActivityEntity = activityVerify.getActivityByCode(bo.getActivityCode());

        /*获得活动限制规则实现类*/
        RestrictInterface restrict = restrictFactory.getRestrict(mallActivityEntity);
        List<MallGoodsToActivityEntity> goodslist = restrict.getList(mallActivityEntity,bo);

        ActivityInfoVo vo =new ActivityInfoVo();
        vo.setMallActivityEntity(mallActivityEntity);
        vo.setGoodslist(goodslist);
        return vo;
    }

    @Override
    public ActivityVerifyVo activityVerify(ActivityGoshoppingBo bo) {
        MallActivityEntity mallActivityEntity = activityVerify.verifyContext(bo.getActivityId());
        RestrictInterface restrict = restrictFactory.getRestrict(mallActivityEntity);
        restrict.verify(bo, mallActivityEntity);
        JSONObject dataJson = restrict.getDataJson(bo, mallActivityEntity);
        ActivityVerifyVo vo =new ActivityVerifyVo();
        vo.setObj(dataJson);
        return vo;
    }

    @Override
    public ParticipantBo activityVerifyTwo(ActivityGoshoppingBo bo) {
        /**验证活动信息，是否在活动期限内等等*/
        MallActivityEntity activity = activityVerify.verifyContext(bo.getActivityId());
        /**限制规则对象*/
        RestrictInterfaceV2 restrictInterfaceV2 = restrictFactoryV2.restrictInterface(activity.getWhitelistConfine());
        /**参与抽奖对象*/
        ParticipantBo restrict = restrictInterfaceV2.restrict(bo,activity);

        return restrict;
    }

    @Override
    public List<ActivityRecordVo> activityRecord(ActivityGoshoppingBo bo) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("limit",bo.getCount());
        params.put("activityId",bo.getActivityId());
        //谢谢惠顾的商品，原来根据goodssn改成根据类型判断
        params.put("noGoodsSn",2);

        Page<MallOrderEntity> page = mallOrderService.selectLimit(params);
        List<MallOrderEntity> records = page.getRecords();
        if (records==null||records.size()==0){
            return null;
        }
        List<ActivityRecordVo> recordVoList =new ArrayList<>(records.size());
        records.forEach(x->{
            MallGoodsEntity goods = mallGoodsService.getById(x.getGoodsId());
            if (goods!=null){
                ActivityRecordVo vo=new ActivityRecordVo();
                vo.setGoodsName(goods.getName());
                vo.setGoodsId(goods.getId());
                vo.setDate(DateUtils.format(x.getAddTime()));
                vo.setPhone(MyStringUtil.hidePhone(x.getMobile()));
                recordVoList.add(vo);
            }

        });
        return recordVoList;
    }

    /**
     * 订单付费成功后修改订单状态
     * @param orderEntity
     * @return
     */
    @Override
    public MallOrderEntity paySuccess(MallOrderEntity orderEntity) {
        CreateOrderUtil.paySuccessUpdateOrderStatus(orderEntity);
        mallOrderService.update(orderEntity);
        return orderEntity;
    }

    /**
     * 直接购买商品下单接口
     * @param bo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized MallOrderEntity directPayOfGoods(DirectGoShoppingBo bo) {

        MallGoodsEntity goods = mallGoodsService.shopping(bo.getGoodsId(), bo.getNumber(), null);
        if (goods==null){
            throw new BusinessException("商品库存不足");
        }
        if (goods.getIsLimited()!=0){
            bo.setMaxNumber(goods.getIsLimited());
            boolean bool = goodsMaxOrderVerify.verify(bo);
            if (!bool){
                throw new BusinessException("该商品超过限购数量");
            }
        }

        MallOrderEntity orderInfo = new MallOrderEntity();

        // 订单类型
        switch (goods.getGoodsType()){
            case 2:
                orderInfo.setOrderType(Constant.MCH_ORDER);
                break;
            case 1:
                orderInfo.setOrderType(Constant.CARD_ORDER);
                break;
            default:

        }

        String orderSn = StringUtils.generateOrderNumber();

        List<MallOrderGoodsEntity> orderGoodsData = new ArrayList<>();

        MallOrderGoodsEntity orderGoodsVo = new MallOrderGoodsEntity();
        orderGoodsVo.setOrderId(orderSn);
        orderGoodsVo.setGoodsId(goods.getId());
        orderGoodsVo.setGoodsSn(goods.getGoodsSn());
        orderGoodsVo.setSkuId(bo.getSkuId());
        orderGoodsVo.setGoodsName(goods.getName());
        orderGoodsVo.setListPicUrl(goods.getListPicUrl());
        orderGoodsVo.setMarketPrice(goods.getMarketPrice());
        orderGoodsVo.setRetailPrice(goods.getRetailPrice());
        orderGoodsVo.setNumber(bo.getNumber());
        orderGoodsVo.setListPicUrl(goods.getListPicUrl());
        // 设置微信优惠标识
        orderGoodsVo.setCouponTag(goods.getGoodsTag());
        orderGoodsVo.setGoodsSpecifitionNameValue("");
        orderGoodsData.add(orderGoodsVo);
        mallOrderGoodsService.saveBatch(orderGoodsData);

        /*设置订单信息*/

        orderInfo.setOrderGoodsEntityList(orderGoodsData);
        // 设置默认的手机号
        orderInfo.setMobile(bo.getMobile());
        orderInfo.setId(orderSn);
        orderInfo.setOrderSn(orderSn);
        orderInfo.setUserId(bo.getUserId());
        orderInfo.setGoodsId(bo.getGoodsId());
        //留言
        orderInfo.setPostscript(bo.getPostscript());
        orderInfo.setAddTime(new Date());
        orderInfo.setExpireTime(DateUtils.addDateMinutes(new Date(), Integer.parseInt(sysConfigService.getValue(Constant.ORDER_EXPIRE, "30"))));
        orderInfo.setShopsId(bo.getShopsId());
        orderInfo.setFromType(bo.getFromType());
        /*// 优惠金额,没有优惠 */
        BigDecimal subPrice = new BigDecimal(0);
        orderInfo.setCouponPrice(subPrice);
        /*计算价格*/
        BigDecimal goodsTotalPrice = goods.getRetailPrice().multiply(BigDecimal.valueOf(bo.getNumber()));
        BigDecimal shippingFee = BigDecimal.valueOf(0);
        BigDecimal orderTotalPrice = goodsTotalPrice.add(shippingFee);
        BigDecimal actualPrice = orderTotalPrice.subtract(subPrice);
        orderInfo.setActualPrice(actualPrice);
        orderInfo.setOrderPrice(orderTotalPrice);
        orderInfo.setShippingFee(shippingFee);
        orderInfo.setIntegralMoney(new BigDecimal(0));
        orderInfo.setNumber(bo.getNumber());
        orderInfo.setUserName(bo.getUname());
        // 收货人 联联订单必填
        orderInfo.setConsignee(bo.getUname());

        /*设置微信优惠标识*/
        orderInfo.setActivityType(goods.getGoodsTag());

        /*设置是否需要付费，不需要付费的直接将订单设置成功状态*/
        orderInfo.setOrderStatus(Constant.OrderStatus.DFK.getValue());
        orderInfo.setShippingStatus(Constant.ShippingStatus.WFH.getValue());
        orderInfo.setPayStatus(Constant.PayStatus.WFK.getValue());
        mallOrderService.save(orderInfo);

        if(orderInfo.getOrderType().intValue() == Constant.MCH_ORDER){
            // 第三方平台下单前检查
            mchOrderService.orders(orderInfo,true);
        }

        return orderInfo;
    }

    /**
     * 取消订单
     *  根据订单信息，找到活动信息
     *  根据活动的信息找到对应的处理
     * @param orderEntity 订单
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized MallOrderEntity cancelOrder(MallOrderEntity orderEntity) {
        MallActivityEntity activity = activityVerify.getActivity(orderEntity.getActivityId());
        RestrictInterface restrict = restrictFactory.getRestrict(activity);
        ActivityGoshoppingBo bo =new ActivityGoshoppingBo();

        bo.setPhone(orderEntity.getMobile());


        List<MallOrderGoodsEntity> list = mallOrderGoodsService.lambdaQuery().eq(MallOrderGoodsEntity::getOrderId, orderEntity.getId()).list();
        for (MallOrderGoodsEntity ordergoods:list){
            bo.setNumber(ordergoods.getNumber());
            restrict.cancel(activity, bo);

            boolean enbool = mallGoodsToActivityService.lambdaUpdate().setSql("expend_count=expend_count+"+bo.getNumber())
                    .eq(MallGoodsToActivityEntity::getGoodsId, ordergoods.getGoodsId())
                    .eq(MallGoodsToActivityEntity::getActivityId, activity.getId())
                    .update();

            boolean bool = mallGoodsService.lambdaUpdate().setSql("goods_number=goods_number+" + bo.getNumber())
                    .eq(MallGoodsEntity::getId, ordergoods.getGoodsId())
                    .update();
        }

        CreateOrderUtil.payFailUpdateOrderStatus(orderEntity);

        mallOrderService.update(orderEntity);

        return orderEntity;
    }
}
